<?php
/**
 * 広告コントローラー
 *
 * @package  app
 * @extends  Controller
 */
class Controller_Api_Ad extends Controller_Apibase {
	/**
	 * コンストラクタ
	 *
	 * @access  public
	 * @return  Response
	 */
	public function before() {
		// 広告系は認証いらない
		$this->auth = false;
		
		parent::before();
		$post = Input::post();
	}

	/**
	 * ポイント追加
	 */
	public function insert_point($member_id, $key1, $key2, $point, $identifer) {
		// 登録開始
		DB::start_transaction();
		try {
			// 有効会員のチェック
			$query = DB::select(DB::expr('count(*) AS count')) -> from('member_info');
			$query -> where("member_id", $member_id);
			$query -> where("member_status", 0);
			$result = $query -> execute() -> as_array();
			if ($result[0]['count'] == 0) {
				$this -> alert("bad_member");
				return false;
			}

			// 付与済みのチェック
			$values = array("member_id" => $member_id, "key1" => $key1, "key2" => $key2);
			$query = DB::select(DB::expr('count(*) AS count')) -> from('member_point');
			$query -> where($values);
			$result = $query -> execute() -> as_array();
			if ($result[0]['count'] > 0) {
				$this -> alert("exists");
				return false;
			}

			// 該当の広告を検索
			$query = DB::select('reward_id');
			$query -> from('reward_view');
			$query -> where('ad_company', $key1);
			$query -> where('ad_id', $identifer);
			$result = $query -> execute() -> as_array();
			if( count($result) > 0 ) {
				$values["reward_id"] = $result[0]['reward_id'];
			}
			
			// ポイント履歴
			$values["point_value"] = $point;
			$query = DB::insert('member_point');
			$query -> set($values);
			$query -> execute();

			// ポイント付与
			$query = DB::update('member_info');
			$query -> set(array("point_has" => DB::expr("point_has+" . $point)));
			$query -> where('member_id', $member_id);
			$query -> execute();

			// コミット
			DB::commit_transaction();
			
		} catch(Exception $e) {
			throw $e;
			$this -> alert($e);
			
			// ロールバック
			DB::rollback_transaction();
			return false;
		}
		
		return true;
	}
	
	/**
	 * AppDriver連携
	 *
	 * ポイント連携APIについて、第3者からアクセスされないよう、IP制限などのアクセス制御を行っていただく必要がございます。
	 *・ユーザへポイント付与を行うタイミングは、弊社システムからポイント連携APIに承認状態の成果データが通知された後に行うようにして下さい。
	 *・同じ成果データがポイント連携APIに再送された場合に、重複してポイントを付与しないようにチェックする処理を設けて下さい。
	 *・ユーザへ付与するポイント数についてはポイント連携APIに承認状態の成果データを通知した際のpointパラメータの値を使って下さい。 ※ECのスポンサーサイトなどの場合、購買後の返品処理などにより報酬金額が変更されることがあるためです。
	 * レスポンス 1:正常終了ポイント付与 0:正常終了ポイント未付与 その他:エラー
	 *
	 * @access  public
	 * @return  Response
	 */
	public function action_appdriver() {
		$get = Input::get();

		// バリデーション
		if (array_search(Input::real_ip(), Config::get('reward_appdrv_ips')) === false) {
			// 許可されないIP
			$this -> alert("appdriver bad_ip");
			return Response::forge(9, D_HTTP_WARNING);
		}
		if (empty($get["identifier"]) || empty($get["achieve_id"]) || !isset($get['point'])) {
			$this -> alert("appdriver bad_param");
			return Response::forge(9, D_HTTP_WARNING);
		}
		
		// 登録
		if( !$this->insert_point($get["identifier"], 'appdrv', $get['achieve_id'], $get['point'], $get['campaign_id']) ) {
			return Response::forge(9, D_HTTP_WARNING);
		}

		return Response::forge(1, D_HTTP_UPDATE);
	}

	/**
	 * SMAAD連携
	 *
	 * user (ユーザーID)
	 * approve (承認、非承認　常に1でリクエストを送信します)
	 * adid (広告案件のID)
	 * net (報酬金額)
	 */
	public function action_smaad() {
		$get = Input::get();

		// バリデーション
		if (array_search(Input::real_ip(), Config::get('reward_smaad_ips')) === false) {
			// 許可されないIP
			$this -> alert("smaad bad_ip");
			return Response::forge(null, D_HTTP_WARNING);
		}
		if ( empty($get['user']) || empty($get['adid']) ) {
			return Response::forge(null, D_HTTP_WARNING);
		}
		$point = ceil($get['net'] * Config::get('reward_smaad_rate'));
		
		// 登録
		if( !$this->insert_point($get["user"], 'smaad', $get['adid'], $point, $get['adid']) ) {
			return Response::forge(null, D_HTTP_WARNING);
		}

		return Response::forge(null, D_HTTP_CACHE);
	}
	 
	/**
	 * CAリワード連携
	 *
	 * $data->{'uid'} ユーザー識別ID
	 * $data->{'cid'} 広告ID
	 * $data->{'action_date'}成果発生日時 
	 * $data->{'amount'} 売上金額
	 * $data->{'point'} ポイント数
	 * $data->{'pid'} 成果地点ID
	 */
	 public function action_ca() {
		$get = Input::get();

		// バリデーション
		if (array_search(Input::real_ip(), Config::get('reward_ca_ips')) === false) {
			// 許可されないIP
			$this -> alert("ca bad_ip");
			return Response::forge(null, D_HTTP_WARNING);
		}		
		if ( empty($get['uid']) || empty($get['cid']) || empty($get['pid'])) {
			return Response::forge(null, D_HTTP_WARNING);
		}
		$point = ceil($get['amount'] * Config::get('reward_ca_rate'));
		
		// 登録
		$key2 = sprintf('%s-%s-%s', $get['cid'], $get['pid'], $get['action_date']);
		if( !$this->insert_point($get['uid'], 'ca', $key2, $point, $get['cid']) ) {
			return Response::forge(-1, D_HTTP_WARNING);
		}

		return Response::forge('OK', D_HTTP_UPDATE);
	}
	 
	/**
	 * affilead連携
	 *
	 * https://commesodo.gtlab.jp/api/ad/affilead/?user=(ユーザー識別情報)&ad=(広告番号)&point=(報酬額) 
	 */
	public function action_affilead() {
		$get = Input::get();

		// バリデーション
		if ( empty($get['user']) || empty($get['ad']) ) {
			return Response::forge(null, D_HTTP_WARNING);
		}
		
		// IP制限できないため、DBに該当広告があるかでセキュリティ対策
		$query = DB::select('reward_id', 'point');
		$query -> from('reward_view');
		$query -> where('ad_company', 'affile');
		$query -> where('ad_id', $get['ad']);
		$result = $query -> execute() -> as_array();
		if( count($result) == 0 ) {
			// 該当なし
			return Response::forge(null, D_HTTP_WARNING);
		}
		
		$point = ceil($get['point'] * Config::get('reward_affilead_rate'));
		
		// 登録
		if( !$this->insert_point($get["user"], 'affile', $get['ad'], $point, $get['ad']) ) {
			return Response::forge(null, D_HTTP_WARNING);
		}

		return Response::forge(null, D_HTTP_UPDATE);
	}
	
	/**
	 * moba8連携
	 *
	 * https://commesodo.gtlab.jp/api/ad/affilead/?user=(ユーザー識別情報)&ad=(広告番号)&point=(報酬額) 
	 */
	public function action_moba8() {
		$get = Input::get();

		// バリデーション
		if ( empty($get['point_id1']) || empty($get['ins_id']) ) {
			return Response::forge(null, D_HTTP_WARNING);
		}
		if ( !isset($get['flash_flg']) || $get['flash_flg'] != 'Y' ) {
			return Response::forge(null, D_HTTP_WARNING);
		}
		$ad_company = 'moba8';
		$ad_id = $get['ins_id'];
		$member_id = $get['point_id1'];
		$pay = $get['pay_money'];
		
		// IP制限できないため、DBに該当広告があるかでセキュリティ対策
		$query = DB::select('reward_id', 'point');
		$query -> from('reward_view');
		$query -> where('ad_company', $ad_company);
		$query -> where('ad_id', $ad_id);
		$result = $query -> execute() -> as_array();
		if( count($result) == 0 ) {
			// 該当なし
			return Response::forge(null, D_HTTP_WARNING);
		}
		
		$point = ceil($pay * Config::get('reward_' . $ad_company . '_rate'));
		
		// 登録
		if( !$this->insert_point($member_id, $ad_company, $ad_id, $point, $ad_id) ) {
			return Response::forge(null, D_HTTP_WARNING);
		}

		return Response::forge(null, D_HTTP_UPDATE);
	}
	
	/**
	 * 汎用成果通知
	 *
	 * ?company=zerogame&id=1&point=10&user=10030
	 */
	public function action_other() {
		$get = Input::get();

		// バリデーション
		if ( empty($get['company']) || empty($get['id']) || empty($get['user']) ) {
			return Response::forge(null, D_HTTP_WARNING);
		}
		
		// IP制限できないため、DBに該当広告があるかでセキュリティ対策
		$query = DB::select('reward_id', 'point');
		$query -> from('reward_view');
		$query -> where('ad_company', $get['company']);
		$query -> where('ad_id', $get['id']);
		$result = $query -> execute() -> as_array();
		if( count($result) == 0 ) {
			// 該当なし
			return Response::forge(null, D_HTTP_WARNING);
		}
		
		// GETパラメーターにあるポイントを優先する
		$point = isset($get['point']) ? $get['point'] : $result[0]['point'];
		
		// 登録
		if( !$this->insert_point($get["user"], $get['company'], $get['id'], $point, $get['id']) ) {
			return Response::forge(null, D_HTTP_WARNING);
		}

		return Response::forge(null, D_HTTP_UPDATE);
	}
	
	/**
	 * クリック成果
	 *
	 * ?i=1235&u=1234
	 */
	public function action_click() {
		$get = Input::get();

		// バリデーション
		if ( empty($get['i']) || empty($get['u']) ) {
			return Response::forge(null, D_HTTP_WARNING);
		}
		$reward_id = $get['i'];
		$member_id = $get['u'];
		
		// IP制限できないため、DBに該当広告があるかでセキュリティ対策
		$query = DB::select('ad_company', 'ad_id', 'point', 'link');
		$query -> from('reward_view');
		$query -> where('reward_id', $reward_id);
		$result = $query -> execute() -> as_array();
		if( count($result) == 0 ) {
			// 該当なし
			return Response::forge(null, D_HTTP_WARNING);
		}
		
		// 登録
		$this->insert_point($member_id, $result[0]['ad_company'], $result[0]['ad_id'], $result[0]['point'], $result[0]['ad_id']);

		// 広告先に遷移
		return Response::redirect($result[0]['link'], 'location', 301);
	}
}
